package com.cyb.beta.shiro;

import com.cyb.beta.core.Constant;
import com.cyb.beta.model.RoleUser;
import com.cyb.beta.model.User;
import com.jfinal.kit.StrKit;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * Created by Administrator on 2015/6/9.
 */
public class ShiroDbRealm extends AuthorizingRealm {

    private static final Logger LOGGER = LoggerFactory.getLogger(ShiroDbRealm.class);

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;

        if (StrKit.isBlank(usernamePasswordToken.getUsername()))
            throw new AccountException("用户名为空");

        try {
            User loginUser = User.dao.searchActiveByUserName(usernamePasswordToken.getUsername());
            String password = loginUser.getStr(User.PASSWORD);
            if (password != null) {
                Subject subject = SecurityUtils.getSubject();
                // 登陆用户设置在session
                subject.getSession().setAttribute(Constant.SHIRO_USER, loginUser);
                return new SimpleAuthenticationInfo(loginUser, password, getName());
            } else {
                throw new AuthenticationException("密码为空");
            }

        } catch (Exception e) {
            final String message = "There was a SQL error while authenticating user [" + usernamePasswordToken.getUsername() + "]";
            LOGGER.error("Exception:{}", e.getMessage(), e);
            throw new AuthenticationException(message, e);
        }
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        if (principals == null) {
            throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
        }
        User loginUser = (User) getAvailablePrincipal(principals);
        // User loginUser = (User) principals.fromRealm(getName()).iterator().next();

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        try {
            // Retrieve roles and permissions from database
            List<RoleUser> roleUsers = RoleUser.dao.searchEnableRoleUserByUserId(loginUser.getLong(User.ID));
            getPermissions(info, loginUser.getStr(User.USERNAME), roleUsers);
        } catch (Exception e) {
            final String message = "There was a SQL error while authorizing user [" + loginUser.getStr(User.USERNAME) + "]";
            if (LOGGER.isErrorEnabled()) {
                LOGGER.error(message, e);
            }
            // Rethrow any SQL errors as an authorization exception
            throw new AuthorizationException(message, e);
        }

        return info;
    }

    protected void getPermissions(SimpleAuthorizationInfo info, String username, List<RoleUser> roleUsers) {
//        //TODO 考虑连表查询
//        for (RoleUser roleUser : roleUsers) {
//            if (!username.equals(Constant.SYSTEM_ADMINISTRATOR)) {
//                List<RoleResc> roleRescs = RoleResc.dao.searchRoleRescByRoleId(roleUser.getInt(RoleUser.ROLE_ID));
//                for (RoleResc roleResc : roleRescs) {
//                    info.addStringPermission(String.valueOf(roleResc.getInt(RoleResc.RESC_ID)));
//                }
//            } else {
//                List<MenuResc> rescs = MenuResc.dao.searchAll(); // 管理员默认获取全部权限
//                for (MenuResc resc : rescs) {
//                    info.addStringPermission(String.valueOf(resc.getStr(MenuResc.PERMISSION)));
//                }
//            }
//
//            info.addRole(String.valueOf(roleUser.getInt(RoleUser.ROLE_ID)));
//        }
    }
}
